package cn.kgc.easybuy.initalizer;

import cn.kgc.easybuy.annotaion.CheckPermission;
import cn.kgc.easybuy.pojo.User;
import cn.kgc.easybuy.service.UserService;
import cn.kgc.easybuy.utils.JwtUtil;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Component
public class UserCheckInterceptor implements HandlerInterceptor {
    private static final Logger log = LoggerFactory.getLogger(UserCheckInterceptor.class);
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private UserService userService;

    @Autowired
    public UserCheckInterceptor(StringRedisTemplate redisTemplate,UserService userService){
        this.redisTemplate = redisTemplate;
        this.userService = userService;
    }

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("请求地址：" + request.getRequestURI());
        String token = request.getHeader("Authorization");
        log.info("token值：" + token);
        if(token == null || token.equals("")){
//            throw new RuntimeException("未登录");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getWriter().write("未登录");
            return false;
        }
        Long userId;
        Long type;
        try{
            userId = JwtUtil.getUserID(token);
            type = JwtUtil.getType(token);
        }catch (SignatureVerificationException e){
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getWriter().write("验签错误");
            //throw new RuntimeException("验签错误");
            return false;
        }catch (TokenExpiredException e){
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getWriter().write("登录超时");
            return false;
            //throw new RuntimeException("登录超时");
        }
        String serverToken = redisTemplate.opsForValue().get(userId.toString());
        if(!token.equals(serverToken)){
            throw new RuntimeException("验签错误");
        }
        Date tokenTime = JwtUtil.getExpires(token);
        if(tokenTime.getTime() - System.currentTimeMillis() <= 5 * 60 * 1000){
            String newToken = JwtUtil.createToken(userId,type);
            redisTemplate.opsForValue().set(userId.toString(),newToken,30, TimeUnit.MINUTES);
            response.setHeader("Access-Control-Expose-Headers","new-token");
            response.setHeader("news-token",newToken);
        }
        boolean isHandlerMethod = handler instanceof HandlerMethod;
        if(!isHandlerMethod){
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        CheckPermission checkPermission = handlerMethod.getMethodAnnotation(CheckPermission.class);
        if(checkPermission == null){
            return true;
        }
        String[] roles = checkPermission.value();
        log.info("角色" + Arrays.toString(roles));

        if(checkRole(userId,roles)){
            return true;
        }else{
            throw new RuntimeException("权限不足");
        }
    }

    public boolean checkRole(long userId,String[] roles){
        User user = userService.selectUserById( (int)userId);
        for(String role : roles){
            if(role.equals(user.getType().toString())){
                return true;
            }
        }
        return false;
    }
}
